home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / answrbok / 8_12.lha / 8_12 / 8_12b5.c < prev    next >
Text File  |  1993-08-08  |  3KB  |  165 lines

  1. * Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
  2. * The C++ Answer Book */
  3. * Tony Hansen */
  4. * All rights reserved. */
  5. / match a pattern on the input stream
  6. / %d looks for an integer & stops at the first
  7. /    non-integer character
  8. / %f looks for a floating point number & stops ...
  9. / %c matches a single character
  10. / %s matches a white-space delineated string
  11. / %% matches %
  12. / ' ' matches any white space
  13. / 'X' matches the character X
  14.  
  15. nt pat::match(char *pattern)
  16.  
  17.    // reset base ptr to pt to beginning of buffer
  18.    ebp->setbuffering();
  19.  
  20.    // loop through the pattern looking
  21.    // for things to match.
  22.    int goodpattern = 1;
  23.    while (*pattern && goodpattern)
  24. {
  25. int c = ebp->sgetc();
  26. char p = *pattern++;
  27.  
  28. / define a couple of small macros for
  29. / some common sequences
  30. define Next()                \
  31.    ebp->stossc(), c = ebp->sgetc()
  32.  
  33. define doloop(testfunc)        \
  34.    do { Next(); } while (testfunc(c))
  35.  
  36. switch (p)
  37.     {
  38.     // space matches arbitrary white space
  39.     case ' ':
  40.     if (isspace(c))
  41.         doloop(isspace);
  42.  
  43.     else
  44.         goodpattern = 0;
  45.     break;
  46.  
  47.     // a pattern: %d, %f, %c, %s, %%
  48.     case '%':
  49.     p = *pattern++;
  50.  
  51.     // check for patterns which
  52.     // toss white space first
  53.     if ((p == 'd') || (p == 'f') ||
  54.         (p == 's'))
  55.         if (isspace(c))
  56.         doloop(isspace);
  57.  
  58.     // now skip past the particular type
  59.     switch (p)
  60.         {
  61.         // decimal number
  62.         case 'd':
  63.         if ((c == '-') || (c == '+'))
  64.             Next();
  65.  
  66.         if (isdigit(c))
  67.             doloop(isdigit);
  68.  
  69.         else
  70.             goodpattern = 0;
  71.         break;
  72.  
  73.         // floating point
  74.         case 'f':
  75.         if ((c == '-') || (c == '+'))
  76.             Next();
  77.  
  78.         int digitsbefore = 0;
  79.         int hasdecimal = 0;
  80.         int digitsafter = 0;
  81.         int hasexponent = 0;
  82.  
  83.         if (isdigit(c))
  84.             {
  85.             digitsbefore = 1;
  86.             doloop(isdigit);
  87.             }
  88.  
  89.         if (c == '.')
  90.             {
  91.             hasdecimal = 1;
  92.             Next();
  93.  
  94.             if (isdigit(c))
  95.             {
  96.             digitsafter = 1;
  97.             doloop(isdigit);
  98.             }
  99.             }
  100.  
  101.         if ((c == 'e') || (c == 'E'))
  102.             {
  103.             hasexponent = 1;
  104.             Next();
  105.  
  106.             if ((c == '-') || (c == '+'))
  107.             Next();
  108.  
  109.             if (isdigit(c))
  110.             doloop(isdigit);
  111.  
  112.             else
  113.             goodpattern = 0;
  114.             }
  115.  
  116.         if (!((digitsbefore &&
  117.                (hasdecimal ||
  118.             hasexponent)) ||
  119.               digitsafter))
  120.             goodpattern = 0;
  121.  
  122.         break;
  123.  
  124.         // any string. leading white
  125.         // space was tossed above
  126.         case 's':
  127.         doloop(!isspace);
  128.         break;
  129.  
  130.         // any single character
  131.         case 'c':
  132.         ebp->stossc();
  133.         break;
  134.  
  135.         // match single %
  136.         case '%':
  137.         if (ebp->sgetc() == '%')
  138.             ebp->stossc();
  139.  
  140.         else
  141.             goodpattern = 0;
  142.         break;
  143.  
  144.         // unknown pattern
  145.         default:
  146.         goodpattern = 0;
  147.         break;
  148.         }
  149.     break;
  150.  
  151.     // non-pattern, match the character
  152.     default:
  153.     if (c == p)
  154.         ebp->stossc();
  155.  
  156.     else
  157.         goodpattern = 0;
  158.     break;
  159.     }
  160. }
  161.  
  162.    ebp->resetbuffering();
  163.    return goodpattern;
  164.  
  165.